package org.bear.mario.Running;

import org.bear.mario.Pojo.Enemy;
import org.bear.mario.Pojo.Mario;
import org.bear.mario.Pojo.Obstruction;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

// MyFrame类，继承自JFrame，实现了KeyListener和Runnable接口
public class MyFrame extends JFrame implements KeyListener, Runnable {

    private Date startTime = new Date();

    private List<BackGround> allBG = new ArrayList<BackGround>();

    private Mario mario = null;

    private BackGround nowBG = null;

    private Thread t = null;

    private boolean isStart = false;

    // 构造函数，用于初始化窗口及游戏的设置
    public MyFrame() {
        this.setTitle("普通马里奥");
        this.setSize(900, 600);
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        this.setLocation((width - 900) / 2, (height - 600) / 2);
        this.setResizable(false);

        StaticValue.init();

        for (int i = 1; i <= 7; i++) {
            this.allBG.add(new BackGround(i, i == 7 ? true : false));
        }

        this.nowBG = this.allBG.get(0);
        this.mario = new Mario(0, 480);
        this.mario.setBg(nowBG);

        this.repaint();

        this.addKeyListener(this);

        this.t = new Thread(this);
        t.start();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    // 绘制游戏界面
    public void paint(Graphics g) {

        BufferedImage image = new BufferedImage(900, 600, BufferedImage.TYPE_3BYTE_BGR);
        Graphics g2 = image.getGraphics();

        if (this.isStart) {
            g2.setFont(new Font("Emojione", Font.PLAIN, 30));
            g2.drawImage(this.nowBG.getBgImage(), 0, 0, this);

            // 添加时间显示组件(第一个参数为时间字符串，第二个参数为坐标)
            long dif = new Date().getTime() - startTime.getTime();
            g2.drawString("时间 : "+(dif/1000/60)+":"+(dif/1000%60), 480, 80);

            g2.drawString("❤ : " + this.mario.getLife(), 650, 80);

            g2.drawString("分数 : " + this.mario.getScore(), 750, 80);

            Iterator<Enemy> iterEnemy = this.nowBG.getAllEnemy().iterator();
            while (iterEnemy.hasNext()) {
                Enemy e = iterEnemy.next();
                g2.drawImage(e.getShowImage(), e.getX(), e.getY(), this);
            }

            Iterator<Obstruction> iter = this.nowBG.getAllObstruction().iterator();
            while (iter.hasNext()) {
                Obstruction ob = iter.next();
                g2.drawImage(ob.getShowImage(), ob.getX(), ob.getY(), this);
            }

            g2.drawImage(this.mario.getShowImage(), this.mario.getX(), this.mario.getY(), this);

        } else {
            g2.drawImage(StaticValue.startImage, 0, 0, this);
        }

        g.drawImage(image, 0, 0, this);

    }

    // 键盘输入处理，当键被输入时调用
    public void keyTyped(KeyEvent e) {

    }

    // 键盘输入处理，当按下键时调用
    public void keyPressed(KeyEvent e) {
        if (this.isStart) {
            if (e.getKeyCode() == 39) {
                this.mario.rightMove();
            }
            if (e.getKeyCode() == 37) {
                this.mario.leftMove();
            }
            if (e.getKeyCode() == 38) {
                this.mario.jump();
            }
        } else if (e.getKeyCode() == 32) {
            this.isStart = true;
            this.nowBG.enemyStartMove();
            this.mario.setScore(0);
            this.mario.setLife(5);
        }
    }

    // 键盘输入处理，当松开键时调用
    public void keyReleased(KeyEvent e) {
        if (this.isStart) {
            if (e.getKeyCode() == 39) {
                this.mario.rightStop();
            }
            if (e.getKeyCode() == 37) {
                this.mario.leftStop();
            }
        }
    }

    // 游戏主循环，控制游戏的运行逻辑
    public void run() {
        while (true) {
            this.repaint();
            try {
                Thread.sleep(50);
                if (this.mario.getX() >= 840) {
                    this.nowBG = this.allBG.get(this.nowBG.getSort());
                    this.mario.setBg(nowBG);
                    this.nowBG.enemyStartMove();
                    this.mario.setX(0);
                }
                if (this.mario.isDead()) {
                    JOptionPane.showMessageDialog(this, " 游戏结束 ");
                    System.exit(0);
                }
                if (this.mario.isClear()) {
                    JOptionPane.showMessageDialog(this, " 游戏通关胜利 ");
                    System.exit(0);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
